/*  
 Copyright 2010 The 'Tribe.Blog' development team  
 (http://tribecache.codeplex.com/team/view)

 This library is licensed under the Ms-PL Microsoft Public License.  You should 
 have received a copy of the license along with the source code.  If not, an online copy
 of the license can be found at http://tribecache.codeplex.com/license.
*/

using System;
using System.Threading;
using Tribe.Cache.Factory;
using Tribe.Cache.Helpers;
using Tribe.Cache.Storage;

namespace Tribe.Cache.Service
{
    ///<summary>
    ///</summary>
    public class CacheExpirationService : IDisposable
    {
        private static volatile Timer _timer;
        private static readonly object TimerSyncRoot = new Object();

        /// <summary>
        /// Start the cache expiration service - cleans out the cache table of any items that have expired
        /// </summary>
        /// <param name="cacheFactory">Cache factory</param>
        /// <param name="invocationSchedule">The time period between invocations of the cache expiration service cleanup task</param>
        public void Start(ICacheFactory cacheFactory, TimeSpan invocationSchedule)
        {
            TimerCallback timerCallback = state => ExpireExpiredCacheItems(CacheFactory.CacheTable);

            if (invocationSchedule.HasTime())
            {
                if (_timer == null)
                {
                    lock (TimerSyncRoot)
                    {
                        if (_timer == null)
                            _timer = new Timer(timerCallback, null, 0, int.Parse(invocationSchedule.TotalMilliseconds.ToString()));
                    }
                }
            }
            else
                throw new ArgumentException(Resources.Resources.CleanupIntervalInvalidMessage);
        }
        /// <summary>
        /// Expire items in the cache table
        /// </summary>
        /// <param name="source">The cache table</param>
        private static void ExpireExpiredCacheItems(CacheTable source)
        {
            source.ClearExpired();
        }
        /// <summary>
        /// Disposes the singleton instance of the cache expiration service
        /// </summary>
        public void Dispose()
        {
            // ReSharper disable RedundantCheckBeforeAssignment
            if(_timer != null)
            // ReSharper restore RedundantCheckBeforeAssignment
                _timer = null;
        }
    }
}